<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>可拖动的绳子</title>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background-color: #f0f0f0;
      }
      canvas {
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <canvas id="ropeCanvas"></canvas>
    <!-- <script src="rope.js"></script> -->
    <script>
      const canvas = document.getElementById("ropeCanvas");
      const ctx = canvas.getContext("2d");

      canvas.width = window.innerWidth * 0.8;
      canvas.height = window.innerHeight * 0.8;

      let startPoint = { x: 100, y: 100 }; // 绳子的起点
      let endPoint = { x: 400, y: 400 }; // 绳子的终点
      let isDragging = false;
      let dragTarget = null;

      function drawRope() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // 绘制绳子的起点和终点
        ctx.beginPath();
        ctx.arc(startPoint.x, startPoint.y, 5, 0, Math.PI * 2);
        ctx.fillStyle = "red";
        ctx.fill();

        ctx.beginPath();
        ctx.arc(endPoint.x, endPoint.y, 5, 0, Math.PI * 2);
        ctx.fillStyle = "red";
        ctx.fill();

        // 绘制贝塞尔曲线
        ctx.beginPath();
        ctx.moveTo(startPoint.x, startPoint.y);

        // 计算控制点，让绳子看起来像垂下来的效果
        const controlPointX = (startPoint.x + endPoint.x) / 2;
        const controlPointY = (startPoint.y + endPoint.y) / 2 + 100; // 增加100是为了让绳子看起来更弯曲

        ctx.bezierCurveTo(
          controlPointX,
          controlPointY,
          controlPointX,
          controlPointY,
          endPoint.x,
          endPoint.y
        );

        ctx.strokeStyle = "black";
        ctx.lineWidth = 2;
        ctx.stroke();
      }

      canvas.addEventListener("mousedown", (e) => {
        const rect = canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;

        if (
          Math.hypot(x - startPoint.x, y - startPoint.y) < 10 ||
          Math.hypot(x - endPoint.x, y - endPoint.y) < 10
        ) {
          isDragging = true;
          dragTarget =
            Math.hypot(x - startPoint.x, y - startPoint.y) < 10
              ? startPoint
              : endPoint;
        }
      });

      canvas.addEventListener("mousemove", (e) => {
        if (isDragging) {
          const rect = canvas.getBoundingClientRect();
          dragTarget.x = e.clientX - rect.left;
          dragTarget.y = e.clientY - rect.top;
          drawRope();
        }
      });

      canvas.addEventListener("mouseup", () => {
        isDragging = false;
      });

      canvas.addEventListener("mouseleave", () => {
        isDragging = false;
      });

      drawRope();
    </script>
  </body>
</html>
